/*
 * Copyright (c) 2012 Qunar.com. All Rights Reserved
 */

package com.pyb.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * ThreadPoolUtil
 *
 * @author chuchen.zhang
 * @date 16-8-29 上午11:51
 */
public class ThreadPoolUtil {

    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolUtil.class);

    public static ThreadPoolExecutor getArrayBlockingQueuePoolExecutor(int corePoolSize
            , int maximumPoolSize
            , long keepAliveTime
            , TimeUnit unit
            , int blockingQueueSize
            , final String tag) {

        logger.info("create thread pool with blocking array queue, tag : {}, corePoolSize : {}, maximumPoolSize : {}"
                    + ", keepAliveTime : {}, unit : {}, blockingQueueSize : {}"
                , tag
                , corePoolSize
                , maximumPoolSize
                , keepAliveTime
                , unit
                , blockingQueueSize);
        return new ThreadPoolExecutor(corePoolSize
                 , maximumPoolSize
                 , keepAliveTime
                 , unit
                 , new ArrayBlockingQueue<Runnable>(blockingQueueSize)
                 , new ThreadFactory() {
                        @Override
                        public Thread newThread(Runnable r) {
                            Thread thread = new Thread(r);
                            thread.setName(StringUtils.join(tag, "_thread"));
                            return thread;
                        }
                    }
                 , new RejectedExecutionHandler() {
                        @Override
                        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                            logger.error(
                                StringUtils.join(tag, "_thread_full:queue_size={}, ActiveCount={}, CorePoolSize={}, CompletedTaskCount={}"),
                                executor.getQueue().size(), executor.getActiveCount(), executor.getCorePoolSize(),
                                executor.getCompletedTaskCount());
                        }
                    }
                );
    }

//    /**
//     * @param tag 区别监控
//     * @param executorService 必须为ThreadPoolExecutor
//     */
//    public static void recordPoolInfo(String tag, ExecutorService executorService) {
//        try {
//            // 减少监控频率
//            if (System.currentTimeMillis() % 1000 > 5l) {
//                return;
//            }
//
//            if (! (executorService instanceof ThreadPoolExecutor)) {
//                QMonitor.recordOne("record_pool_info_type_error");
//                return;
//            }
//
//            ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;
//            QMonitor.recordOne(StringUtils.join(tag, "_pool_active_count"), executor.getActiveCount());
//            QMonitor.recordOne(StringUtils.join(tag, "_pool_queue_size"), executor.getQueue().size());
//            QMonitor.recordOne(StringUtils.join(tag, "_pool_size"), executor.getPoolSize());
//            QMonitor.recordOne(StringUtils.join(tag, "_pool_core_size"), executor.getCorePoolSize());
//        } catch (Exception e) {
//            logger.error("record pool info error", e);
//            QMonitor.recordOne("record_pool_info_error");
//        }
//    }
}
